package com.hb.trade.server.project.deal.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hb.core.pojo.enums.SectionStatusEnum;
import com.hb.core.pojo.parent.PageResult;
import com.hb.core.pojo.project.deal.dto.BidCandidateDTO;
import com.hb.core.pojo.project.deal.dto.BidCandidateSectionDTO;
import com.hb.core.pojo.project.deal.dto.BidCandidateSupplierDTO;
import com.hb.core.pojo.project.deal.entity.BidCandidate;
import com.hb.core.pojo.project.deal.entity.BidCandidateSection;
import com.hb.core.pojo.project.deal.entity.BidCandidateSupplier;
import com.hb.core.pojo.project.opening.dto.OpeningBidTenderDTO;
import com.hb.core.pojo.project.opening.entity.OpeningBidTender;
import com.hb.core.pojo.project.proj.enums.BidWayEnum;
import com.hb.core.pojo.project.section.entity.BidSection;
import com.hb.trade.server.project.deal.service.BidCandidateSectionService;
import com.hb.trade.server.project.deal.service.BidCandidateService;
import com.hb.trade.server.project.deal.service.BidCandidateSupplierService;
import com.hb.trade.server.project.opening.service.OpeningBidHallService;
import com.hb.trade.server.project.section.manager.BidSectionManager;
import com.hb.trade.server.project.section.service.raw.BidSectionOfferService;
import com.hb.trade.server.project.section.service.raw.BidSectionService;
import com.hb.trade.server.project.section.service.raw.TradeSecondQuotationBidInfoService;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.util.MsgUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 中标候选人公示Controller控制器
 *
 * @author Lix1ang
 * @date 2021-12-24 14:01:54
 */
@RestController
public class BidCandidateController {

    protected final BidCandidateService bidCandidateService;
    protected final BidCandidateSectionService bidCandidateSectionService;
    protected final BidCandidateSupplierService bidCandidateSupplierService;
    protected final OpeningBidHallService openingBidHallService;
    protected final BidSectionService bidSectionService;
    protected final BidSectionOfferService bidSectionOfferService;
    private final TradeSecondQuotationBidInfoService tradeSecondQuotationBidInfoService;

    public BidCandidateController(BidCandidateService bidCandidateService,
                                  BidCandidateSectionService bidCandidateSectionService,
                                  BidCandidateSupplierService bidCandidateSupplierService,
                                  OpeningBidHallService openingBidHallService,
                                  BidSectionService bidSectionService,
                                  BidSectionOfferService bidSectionOfferService,
                                  TradeSecondQuotationBidInfoService tradeSecondQuotationBidInfoService) {
        this.bidCandidateService = bidCandidateService;
        this.bidCandidateSectionService = bidCandidateSectionService;
        this.bidCandidateSupplierService = bidCandidateSupplierService;
        this.openingBidHallService = openingBidHallService;
        this.bidSectionService = bidSectionService;
        this.bidSectionOfferService = bidSectionOfferService;
        this.tradeSecondQuotationBidInfoService = tradeSecondQuotationBidInfoService;
    }

    /**
     * 根据项目Id查询候选人公示列表
     *
     * @param bidCandidateDTO
     * @return
     */
    @PostMapping("/candidate/getCandidateByProjectId")
    public Message<PageResult> getCandidateByProjectId(@RequestBody BidCandidateDTO bidCandidateDTO) {
        if (null == bidCandidateDTO.getProjectId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        Page<BidCandidate> bidCandidatePage = this.bidCandidateService.findCandidatePage(bidCandidateDTO);

        return MsgUtil.success(PageResult.get(bidCandidatePage));
    }

    /**
     * 根据标段id查询候选人公示
     *
     * @param bidCandidateDTO
     * @return
     */
    @PostMapping("/candidate/getCandidateBySectionId")
    public Message<List<BidCandidateDTO>> getCandidateBySectionId(@RequestBody BidCandidateDTO bidCandidateDTO) {
        if (null == bidCandidateDTO.getSectionId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        //根据标段Id查询发布过候选人公示的结果集，包括首次及变更公示
        List<BidCandidateSection> bidCandidateSectionList = bidCandidateSectionService.list(
                new LambdaQueryWrapper<BidCandidateSection>()
                .eq(BidCandidateSection::getSectionId, bidCandidateDTO.getSectionId()));
        if (CollUtil.isEmpty(bidCandidateSectionList)) {
            return MsgUtil.fail("此标段还未发布候选人公示");
        }
        List<BidCandidateDTO> bidCandidateList = new ArrayList<>();
        for (BidCandidateSection bidCandidateSection : bidCandidateSectionList) {
            BidCandidate bidCandidate = bidCandidateService.getOne(new LambdaQueryWrapper<BidCandidate>()
                    .eq(BidCandidate::getId, bidCandidateSection.getCandidateId())
                    .eq(BidCandidate::getStatus, 3));
            if (bidCandidate == null){
                continue;
            }
            bidCandidateList.add(bidCandidate.to(BidCandidateDTO.class));
        }
        return MsgUtil.success(bidCandidateList);
    }

    /**
     * 获取候选人公示详情  --根据主键Id
     *
     * @param bidCandidateDTO
     * @return
     */
    @PostMapping("/candidate/getCandidateDetail")
    public Message<BidCandidateDTO> getCandidateDetail(@RequestBody BidCandidateDTO bidCandidateDTO) {
        if (null == bidCandidateDTO.getId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        BidCandidate bidCandidate = bidCandidateService.getBidCandidateDTOById(bidCandidateDTO.getId());
        if (null == bidCandidate) {
            return MsgUtil.fail(MsgEnum.FAILURE.msg());
        }
        //查询标段列表
        PageResult<BidCandidateSectionDTO> bidCandidateSectionDTOPageResult =
                bidCandidateSectionService.listSectionByCandidateId(new Page(), bidCandidate.getId());
        List<BidCandidateSectionDTO> bidCandidateSectionDTOList = bidCandidateSectionDTOPageResult.getRecords();
        for (BidCandidateSectionDTO bidCandidateSectionDTO : bidCandidateSectionDTOList) {
            //查询候选人列表
            List<BidCandidateSupplier> bidCandidateSupplierList = bidCandidateSupplierService.list(
                    new LambdaQueryWrapper<BidCandidateSupplier>()
                    .eq(BidCandidateSupplier::getCandidateId, bidCandidate.getId())
                    .eq(BidCandidateSupplier::getSectionId, bidCandidateSectionDTO.getSectionId()));
            bidCandidateSectionDTO.setCandidateSupplierList(bidCandidateSupplierList);
        }
        bidCandidateDTO = bidCandidate.to(BidCandidateDTO.class);
        bidCandidateDTO.setCandidateSectionList(bidCandidateSectionDTOList);
        if (CollUtil.isEmpty(bidCandidateSectionDTOList)){
            return MsgUtil.success(bidCandidateDTO);
        }
        List<Long> bidSectionList = bidCandidateSectionDTOList.stream().map(BidCandidateSectionDTO::getSectionId).collect(Collectors.toList());
        List<BidSection> bidSections = bidSectionService.listByIds(bidSectionList);
        bidCandidateDTO.setBidSectionList(bidSections);
        return MsgUtil.success(bidCandidateDTO);
    }

    /**
     * 新增或者修改中标候选人公示
     *
     * @param bidCandidateDTO
     * @return
     */
    @PostMapping("/candidate/saveOrUpdateCandidate")
    public Message saveOrUpdateCandidate(@RequestBody BidCandidateDTO bidCandidateDTO) {
        Boolean result = false;
        if (null == bidCandidateDTO.getProjectId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        List<BidCandidateSectionDTO> candidateSectionList = bidCandidateDTO.getCandidateSectionList();
        if (CollUtil.isEmpty(candidateSectionList)) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        if (null == bidCandidateDTO.getId()) {
            result = this.bidCandidateService.addCandidate(bidCandidateDTO);
        } else {
            //获取当前操作为第几步
            if (null == bidCandidateDTO.getDataFormFlag()) {
                return MsgUtil.fail("缺少操作标识(dataFormFlag)参数");
            }
            result = this.bidCandidateService.updateCandidate(bidCandidateDTO);
        }
        return result ?  MsgUtil.success(bidCandidateDTO.getId()) : MsgUtil.msg(MsgEnum.FAILURE.msg());
    }

    /**
     * 候选人发布
     *
     * @param bidCandidateDTO  (id:主键Id)
     * @return
     */
    @PostMapping("/candidate/publishCandidate")
    public Message publishCandidate(@RequestBody BidCandidateDTO bidCandidateDTO) {
        if (null == bidCandidateDTO.getId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        BidCandidate bidCandidate = bidCandidateService.getById(bidCandidateDTO.getId());
        if (null == bidCandidate) {
            return MsgUtil.fail(MsgEnum.FAILURE.msg());
        }
        if (bidCandidate.getStatus() == 3) {
            return MsgUtil.fail("请勿重复发布");
        }
        if (CollUtil.isEmpty(bidCandidate.getPublicityContentSignature())) {
            return MsgUtil.fail("请先执行签章操作");
        }
        //设置为发布状态
        bidCandidateDTO.setStatus(3);
        Boolean result = bidCandidateService.updateById(bidCandidateDTO);

        if (!result){
            return MsgUtil.fail(MsgEnum.FAILURE.msg());
        }
        //更新标段状态
        List<BidCandidateSection> bidCandidateSections = bidCandidateSectionService.listBidCandidateByCandidateId(bidCandidateDTO.getId());
        if(CollUtil.isEmpty(bidCandidateSections)){
            return MsgUtil.success();
        }
        for (BidCandidateSection bidCandidateSection : bidCandidateSections) {
            BidSection bidSection = bidSectionService.getById(bidCandidateSection.getSectionId());
            if (bidSection == null){
                continue;
            }
            BidSectionManager bidSectionManager = bidSection.to(BidSectionManager.class);
            bidSectionManager.refreshBidSection();
        }
        return MsgUtil.success();
    }

    /**
     * 获取未被关联的标段
     *
     * @param bidCandidateDTO (根据项目Id跟候选人公示Id)
     * @return
     */
    @PostMapping("/candidate/getSectionNotSelected")
    public Message<PageResult> getSectionNotSelected(@RequestBody BidCandidateDTO bidCandidateDTO) {
        if (null == bidCandidateDTO.getProjectId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        //查询未被关联并且开标结束的标段结果集
        bidCandidateDTO.setSectionStatus(SectionStatusEnum.BID_ASSESSING.getId());
        PageResult<BidSection> sectionPage = bidCandidateSectionService.getSectionNotSelected(bidCandidateDTO);
        return MsgUtil.success(sectionPage);
    }

    /**
     * 获取中标候选人公示列表（从开标记录表里拉取投标人信息）
     *
     * @param bidCandidateSupplier
     * @return
     */
    @PostMapping("/candidate/getCandidate")
    public Message<PageResult> getCandidate(@RequestBody BidCandidateSupplier bidCandidateSupplier) {
        if (null == bidCandidateSupplier.getSectionId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        PageResult<OpeningBidTenderDTO> pageResult = bidCandidateService.getCandidate(bidCandidateSupplier);
        return MsgUtil.success(pageResult);
    }

    /**
     * 根据候选人公示查询关联标段列表
     *
     * @param bidCandidateDTO
     * @return
     */
    @PostMapping("/candidate/listSectionByCandidateId")
    public Message<PageResult> listSectionByCandidateId(@RequestBody BidCandidateDTO bidCandidateDTO) {
        if (null == bidCandidateDTO.getId()) {
            return MsgUtil.fail(MsgEnum.INCORRECT_PARAM.msg());
        }
        PageResult<BidCandidateSectionDTO> sectionPage = bidCandidateSectionService.listSectionByCandidateId(
                bidCandidateDTO.pages(), bidCandidateDTO.getId());
        return MsgUtil.success(sectionPage);
    }

    /**
     *
     * @Description:查询标段的中标候选人公示最后一次中标人候选人列表
     * @Author: zhongdl
     * @Date:2022/1/6 9:00
     * @param bidCandidateSupplierDTO:
     * @return: {@link Message< PageResult< BidCandidateSupplierDTO>> }
     **/
    @PostMapping("/candidate/pageCandidate")
    public Message<PageResult<BidCandidateSupplierDTO>> pageCandidate(@RequestBody BidCandidateSupplierDTO bidCandidateSupplierDTO){
        // 获取招标方式
        Integer bidWay = bidSectionService.selectBidWayBySectionId(bidCandidateSupplierDTO.getSectionId());
        // 查询多伦报价是否结束
        if (null != bidWay && bidWay.equals(BidWayEnum.NEG.getCode()) || bidWay.equals(BidWayEnum.CON.getCode())) {
            // 查询多伦报价是否结束
            Boolean aBoolean = tradeSecondQuotationBidInfoService.selectEndType(bidCandidateSupplierDTO.getSectionId());
            if (!aBoolean) {
                return MsgUtil.fail("多伦报价暂未结束，请先结束多伦报价");
            }
        }

        Page pages = bidCandidateSupplierDTO.pages();

        //查询最后一次发布中标候选人公示
        Long lastBidCandidateId = bidCandidateService.getLastBidCandidateId(bidCandidateSupplierDTO.getSectionId());
        //查询中标人列表
        PageResult<BidCandidateSupplierDTO> bidCandidateSuppliers = bidCandidateSupplierService.pageCandidate(pages,bidCandidateSupplierDTO.getSectionId(),lastBidCandidateId,bidCandidateSupplierDTO.getOrgName());

        if (CollUtil.isNotEmpty(bidCandidateSuppliers.getRecords())) {
            for (BidCandidateSupplierDTO record : bidCandidateSuppliers.getRecords()) {
                // 如果是竞争性谈判，竞争性磋商 则需要查询多伦报价的信息
                if (null != bidWay && bidWay.equals(BidWayEnum.NEG.getCode()) || bidWay.equals(BidWayEnum.CON.getCode())) {
                    String lastOfferParamValue = bidSectionOfferService.getLastOfferParamValue(record.getBidderId(), record.getSectionId());
                    record.setSuccessfulAmount(new BigDecimal(lastOfferParamValue));
                } else {
                    //设置中标金额
                    BigDecimal winAmount = openingBidHallService.getWinAmount(record.getSectionId(), record.getOrgId());
                    record.setSuccessfulAmount(winAmount);
                }
            }
            return MsgUtil.success(bidCandidateSuppliers);
        }
        // 如果中标候选人公示查不到 再去开标记录查所有的投标人
        OpeningBidTender openingBidTender = new OpeningBidTender();
        bidCandidateSupplierDTO.to(openingBidTender);
        Page<OpeningBidTender> pageTender = openingBidTender.pages();
        PageResult<OpeningBidTender> openingBidTenderPageResult = openingBidHallService.pageOpeningBidTender(pageTender, openingBidTender.getSectionId(), bidCandidateSupplierDTO.getOrgName());
        bidCandidateSuppliers = openingBidTenderPageResult.transferTo(BidCandidateSupplierDTO.class);

        if (CollUtil.isEmpty(bidCandidateSuppliers.getRecords())){
            return MsgUtil.success(bidCandidateSuppliers);
        }

        for (BidCandidateSupplierDTO record : bidCandidateSuppliers.getRecords()) {
            String decryptContent = record.getDecryptContent();

            // 如果是竞争性谈判，竞争性磋商 则需要查询多伦报价的信息
            if (null != bidWay && bidWay.equals(BidWayEnum.NEG.getCode()) || bidWay.equals(BidWayEnum.CON.getCode())) {
                String lastOfferParamValue = bidSectionOfferService.getLastOfferParamValue(record.getBidderId(), record.getSectionId());
                record.setSuccessfulAmount(new BigDecimal(lastOfferParamValue));
            }else {
                //设置中标金额
                BigDecimal winAmount = openingBidHallService.getWinAmount(record.getSectionId(),record.getOrgId());
                record.setSuccessfulAmount(winAmount);
            }

            if (StrUtil.isEmpty(decryptContent)){
                continue;
            }
            JSONObject jsonObject = JSONUtil.parseObj(decryptContent);
            record.setOrgName(jsonObject.get("企业名称",String.class));
        }

        return MsgUtil.success(bidCandidateSuppliers);
    }

    /**
     *
     * @Description: 查询需要推送的中标候选人公示列表
     * @Author: zhongdl
     * @Date:2022/2/23 16:20
     * @param bidCandidateSupplierDTO:
     * @return: {@link Message< List< BidCandidateDTO>> }
     **/
    @PostMapping("/candidate/listPushBidCandidateDTO")
    public Message<List<BidCandidateDTO>> listPushBidCandidateDTO(@RequestBody BidCandidateSupplierDTO bidCandidateSupplierDTO){
        List<BidCandidateDTO> bidCandidateDTOList = bidCandidateService.listPushBidCandidateDTO();
        if (CollUtil.isEmpty(bidCandidateDTOList)){
            return MsgUtil.success(bidCandidateDTOList);
        }
        for (BidCandidateDTO bidCandidateDTO : bidCandidateDTOList) {
            List<BidCandidateSectionDTO> bidCandidateSectionDTOList = CollUtil.list(false);
            List<BidCandidateSection> bidCandidateSections = bidCandidateSectionService.listBidCandidateByCandidateId(bidCandidateDTO.getId());
            for (BidCandidateSection bidCandidateSection : bidCandidateSections) {
                BidCandidateSectionDTO bidCandidateSectionDTO = bidCandidateSection.to(BidCandidateSectionDTO.class);
                BidSection bidSection = bidSectionService.getById(bidCandidateSection.getSectionId());
                bidCandidateSectionDTO.setSectionCode(bidSection.getSectionCode());
                bidCandidateSectionDTO.setSectionName(bidSection.getSectionName());
                List<BidCandidateSupplierDTO> bidCandidateSupplierDTOS = bidCandidateSupplierService.listBidCandidateSupplierDTO(bidCandidateSection.getSectionId(), bidCandidateDTO.getId());
                bidCandidateSectionDTO.setCandidateSupplierDTOList(bidCandidateSupplierDTOS);
                bidCandidateSectionDTOList.add(bidCandidateSectionDTO);
            }
            bidCandidateDTO.setCandidateSectionList(bidCandidateSectionDTOList);
            if (CollUtil.isEmpty(bidCandidateSections)){
                continue;
            }
            BidCandidateSection bidCandidateSection = bidCandidateSections.get(0);
            if (bidCandidateSection == null){
                continue;
            }
            BidCandidateSectionDTO bidCandidateSectionDTO = bidCandidateSection.to(BidCandidateSectionDTO.class);
            List<BidCandidateSupplierDTO> bidCandidateSupplierDTOS = bidCandidateSupplierService.listBidCandidateSupplierDTO(bidCandidateDTO.getSectionId(), bidCandidateDTO.getId());
            bidCandidateSectionDTO.setCandidateSupplierDTOList(bidCandidateSupplierDTOS);
            bidCandidateDTO.setBidCandidateSection(bidCandidateSectionDTO);

        }
        return MsgUtil.success(bidCandidateDTOList);
    }

}
